/*
 * Noun type for vacuum command
 */
var noun_type_vacmode = {
  label: "vacmode",

  modes: [
    _("places"),
    _("all")
  ],
 
  getModes: function() {
    var string = "";
    for (var i = 0; i < this.modes.length; i++) {
      string += this.modes[i];
      if (i < this.modes.length - 1) {
        string += ", ";
      }
    }
    return string;
  },

  suggest: function(text, html, callback, selectionIndices) {
    var suggestions  = [];
    for (var i = 0; i < this.modes.length; i++) {
      if (this.modes[i].match(text, "i")) {
        suggestions.push(CmdUtils.makeSugg(this.modes[i]));
      }
    }
    return suggestions;
  }
}

/*
 * Ubiquity command vacuum
 */
CmdUtils.CreateCommand({
  names: ["vacuum", "vac"],
  icon: "https://developer.mozilla.org/favicon.ico",
  homepage: "http://boardraider-ubiquity-commands.googlecode.com/svn/trunk/vacuum.html",
  author: {name: "boardraider"},
  license: "GPL 2 or newer",
  description: "Executes the VACUUM statement on SQLite files. Requires Firefox 3.5 or higher",
  help: "May take some time when vacuuming big database files like places.sqlite or urlclassifier3.sqlite.",
  arguments: [{
               role: "object",
               nountype: noun_type_vacmode,
               label: "vacuum mode"
             }],

  preview: function(pblock, mode) {
    var varText;
    switch (mode.object.text) {
      case "places":
        varText =  _(" on your places.sqlite.")
        break;
      case "all":
        varText =  _(" on all .sqlite databases in your profile folder (except cookies.sqlite).")
        break;
      default:
        varText = _(". Please select a vaccum mode [") + noun_type_vacmode.getModes() + _("].");
        break;
    }
    pblock.innerHTML = _("Executes the VACUUM statement") + varText;
  },
  
  execute: function(mode) {
    // Check for app version, Firefox 3.5 or higher required
    var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
                            .getService(Components.interfaces.nsIXULAppInfo);
    var versionChecker = Components.classes["@mozilla.org/xpcom/version-comparator;1"]
                                   .getService(Components.interfaces.nsIVersionComparator);
    if(versionChecker.compare(appInfo.version, "3.5") < 0) {
       displayMessage(_("Command requires Firefox 3.5 or higher"));
       return;
    }
    var fileList = new Array();
    var profDir = Components.classes["@mozilla.org/file/directory_service;1"]
                    .getService(Components.interfaces.nsIProperties)
                    .get("ProfD", Components.interfaces.nsIFile);
    var file;
    switch (mode.object.text) {
      case "places":
        file = profDir.clone();
        file.append("places.sqlite");
        fileList.push(file);               
        break;
      case "all":
        var item;
        var items = profDir.directoryEntries;
        while (items.hasMoreElements()) {
          item = items.getNext().QueryInterface(Components.interfaces.nsIFile);
          if (item.isFile() && item.leafName.match(/\.sqlite$/)) {
            file = profDir.clone();
            file.append(item.leafName);
            fileList.push(file);
          }
        }
        break;
      default:
        return;
        break;
    }
    
    function getDBConnection(aDbFile) {
      var dbConn = null;
      switch (aDbFile.leafName.toLowerCase()) {
        case "places.sqlite":
          // http://mxr.mozilla.org/mozilla1.9.1/source/toolkit/components/places/public/nsPIPlacesDatabase.idl
          dbConn = Components.classes["@mozilla.org/browser/nav-history-service;1"]
                             .getService(Components.interfaces.nsPIPlacesDatabase).DBConnection;
          break;
        case "formhistory.sqlite":
          // http://mxr.mozilla.org/mozilla1.9.1/source/toolkit/components/satchel/public/nsIFormHistory.idl
          dbConn = Components.classes["@mozilla.org/satchel/form-history;1"]
                             .getService(Components.interfaces.nsIFormHistory2).DBConnection;
          break;
        case "content-prefs.sqlite":
          // http://mxr.mozilla.org/mozilla1.9.1/source/toolkit/components/contentprefs/public/nsIContentPrefService.idl
          dbConn = Components.classes["@mozilla.org/content-pref/service;1"]
                             .getService(Components.interfaces.nsIContentPrefService).DBConnection;
          break;
        case "downloads.sqlite":
          // http://mxr.mozilla.org/mozilla1.9.1/source/toolkit/components/downloads/public/nsIDownloadManager.idl
          dbConn = Components.classes["@mozilla.org/download-manager;1"]
                             .getService(Components.interfaces.nsIDownloadManager).DBConnection;
          break;
        case "cookies.sqlite":
          // https://bugzilla.mozilla.org/show_bug.cgi?id=476167
          break;
        default:
          try {
            var storageService = Components.classes["@mozilla.org/storage/service;1"]
                                           .getService(Components.interfaces.mozIStorageService);
            dbConn = storageService.openUnsharedDatabase(aDbFile);
          } catch (e) {
            CmdUtils.log(e);
            displayMessage(e);
          }
      }
      return dbConn;
    }
    
    var file, fileName, dbConn;
    for (var i = 0; i < fileList.length; i++) {
      file = fileList[i];
      dbConn = getDBConnection(file);
      if (dbConn) {
        fileName = file.leafName.toLowerCase();
        dbConn.executeSimpleSQL("VACUUM");
        CmdUtils.log(_("Vacuuming ") + fileName + _(" finished."));
        switch(fileName) {
          case "places.sqlite":
          case "formhistory.sqlite":
          case "content-prefs.sqlite":
          case "downloads.sqlite":
            break;
          default:
           try { 
             dbConn.close();
           } catch(e) {
             CmdUtils.log(_("Error closing database connection to ") + fileName + ":" + e);
           }
        }
      }
    }
    displayMessage(_("Finished vaccuming."));
  }
});
